/**
 * 
 */
package org.gbif.metrics.ws.resources.provider;

import org.gbif.metrics.cube.occurrence.OccurrenceCube;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.Provider;

import com.google.common.collect.Maps;
import com.google.inject.Singleton;
import com.sun.jersey.api.core.HttpContext;
import com.sun.jersey.api.model.Parameter;
import com.sun.jersey.core.spi.component.ComponentContext;
import com.sun.jersey.core.spi.component.ComponentScope;
import com.sun.jersey.spi.inject.Injectable;
import com.sun.jersey.spi.inject.InjectableProvider;
import com.urbanairship.datacube.ReadBuilder;


/**
 * A provider that will convert parameters from the request into Cube dimensions.
 */
@Provider
@Singleton
public class CubeDimensionProvider implements InjectableProvider<QueryParam, Parameter> {

  @Context
  private final HttpContext hc;


  public CubeDimensionProvider(@Context HttpContext hc) {
    this.hc = hc;
  }

  /**
   * Maps the request to the dimensions.
   */
  @Override
  public Injectable<ReadBuilder> getInjectable(final ComponentContext ic, final QueryParam a, final Parameter c) {
    return new Injectable<ReadBuilder>() {

      @Override
      public ReadBuilder getValue() {
        MultivaluedMap<String, String> params = hc.getUriInfo().getQueryParameters();
        // We only accept 1 value per parameter
        Map<String, String> kvp = Maps.newHashMap();
        for (Entry<String, List<String>> param : params.entrySet()) {
          kvp.put(param.getKey(), param.getValue().iterator().next());
        }
        return OccurrenceCube.interpretedReadBuilder(kvp);
      }
    };
  }

  @Override
  public ComponentScope getScope() {
    return ComponentScope.PerRequest;
  }
}
